package cn.com.cetccst.compliancecheck.violation;

import static cn.com.cetccst.datacenter.policy.entity.ComplianceBase.ACTION_FACTORY_RESET;
import static cn.com.cetccst.datacenter.policy.entity.ComplianceBase.ACTION_FACTORY_RESET_NOT_INCLUDED;
import static cn.com.cetccst.datacenter.policy.entity.ComplianceBase.ACTION_LOCK;
import static cn.com.cetccst.datacenter.policy.entity.ComplianceBase.ACTION_QUIT;
import static cn.com.cetccst.datacenter.policy.entity.ComplianceBase.ACTION_SKIP;
import static cn.com.cetccst.datacenter.policy.entity.ComplianceBase.ACTION_UN_ENROLL;
import static cn.com.cetccst.datacenter.policy.entity.ComplianceBase.ACTION_WARN;
import static cn.com.cetccst.deviceoperation.OperatorType.LOCK_DEVICE;
import static cn.com.cetccst.deviceoperation.OperatorType.RESET;
import static cn.com.cetccst.deviceoperation.OperatorType.UNREGISTER;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;

import androidx.lifecycle.LiveData;

import java.util.List;

import cn.com.cetccst.compliancecheck.R;
import cn.com.cetccst.compliancecheck.checker.CheckResult;
import cn.com.cetccst.compliancecheck.kv.KVKeys;
import cn.com.cetccst.datacenter.policy.PolicyRepository;
import cn.com.cetccst.datacenter.policy.entity.ComplianceEntity;
import cn.com.cetccst.deviceoperation.DeviceOperator;
import cn.com.cetccst.tools.kv.CommonKV;
import cn.com.cetccst.tools.log.CommonLogger;
import cn.com.cetccst.tools.notification.NotificationUtil;

public class ActionManager {

    private static ActionManager instance;

    private ActionManager(Context context) {
        LiveData<List<ComplianceEntity>> complianceStatusList = PolicyRepository.getInstance().getAllCompliance();
        complianceStatusList.observeForever(complianceEntities -> {
            for (ComplianceEntity entity : complianceEntities) {
                long scheduledPunishTime = CommonKV.kvStore.decodeLong(KVKeys.KEY_COMPLIANCE + entity.getKey());
                if (entity.getStatus() == CheckResult.Violated.getStatus()
                        && entity.getPunish() != ACTION_SKIP
                        && scheduledPunishTime > 0) {
                    //TODO 要不要改为worker来处理？
                    long currentElapsed = System.currentTimeMillis();
                    if (scheduledPunishTime <= currentElapsed) {
                        CommonLogger.info("It is time to execute punishment of field: "
                                + entity.getKey() + " with punish action:" + entity.getPunish());
                        CommonLogger.info("Current elapsedRealTime: " + currentElapsed);
                        executePunish(context, entity, entity.getPunish());
                    } else {
                        CommonLogger.info("Pending punishment of " + entity.getKey()
                                + " with punish action:" + entity.getPunish() + " will execute in " + scheduledPunishTime
                                + ". Current elapsedRealtime:" + currentElapsed);
                    }
                }
            }
        });
    }

    private void executePunish(Context context, ComplianceEntity entity, int punish) {
        switch (punish) {
            case ACTION_SKIP -> CommonLogger.info("Skip violation punishment due to policy set.");
            case ACTION_WARN -> warnNotification(context, entity);
            case ACTION_QUIT ->
                    CommonLogger.debug("TODO: Force quite secured apps due to violation.");
            case ACTION_LOCK -> DeviceOperator.getInstance().operate(LOCK_DEVICE);
            case ACTION_UN_ENROLL -> DeviceOperator.getInstance().operate(UNREGISTER);
            case ACTION_FACTORY_RESET, ACTION_FACTORY_RESET_NOT_INCLUDED ->
                    DeviceOperator.getInstance().operate(RESET);
        }
    }

    private void warnNotification(Context context, ComplianceEntity entity) {
        CommonLogger.info("Display warn notification due to violation.");
        CommonKV.kvStore.encode(KVKeys.KEY_COMPLIANCE + entity.getKey(), -1);
//
        String title = context.getString(R.string.violation_action_warn_title);
        //TODO 根据违规详情修改提示语
        String body = context.getString(R.string.violation_action_warn_body);

        //TODO 跳转参数后期修复
//        Intent notifyIntent = new Intent();
//        notifyIntent.setClassName(context, context.getString(R.string.mdm_compliance_result_activity_impl));
//        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notifyIntent, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
//
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        if (notificationManager == null) {
            return;
        }

        String channelId = "violation";
        NotificationChannel channel = NotificationUtil.generateChannel(channelId);
        channel.setShowBadge(false);
        notificationManager.createNotificationChannel(channel);

        Notification notification = NotificationUtil.generateNotification(context, channelId, title, body, R.drawable.ic_warning, null);
        notificationManager.notify(NotificationUtil.getNotificationId(channelId), notification);
    }

    public static void initialize(Context context) {
        if (instance == null) {
            instance = new ActionManager(context);
        }
    }

    public static ActionManager getInstance() {
        return instance;
    }
}
